iT邦幫忙

2021 iThome 鐵人賽

DAY 29
1
Modern Web

初學者跪著學JavaScript系列 第 29

初學者跪著學JavaScript Day29 : async 和 await

  • 分享至 

  • xImage
  •  

一日客語:中文:成功 客語:ㄙㄣ3聲 ㄍㄨㄥˊ siinˇ gungˊ

出現asyncawait可以更簡單的使用 Promise

配 code 再複習一下 Promise 吧

1.會有 new Promise 創建一個 Promise 物件,此時狀態是: pending 狀態

2.Promise callback function 有 resolve、 reject ,狀態會改變會有 fulfilled 、 rejected

3.外面要接收透過 Promise 物件的 then 和 catch methods

function woman() {
    let randomNumber = Math.random() * 3;
    let random = Math.floor(randomNumber);
    return new Promise(function (resolve, reject) {
        if (random === 1) {
            return resolve('嫁');
        } else {
            return reject('不嫁');
        }
    });
}
woman()
    .then((yes) => console.log(yes, '女主角說願意,求婚成功'))
    .catch((no) => console.log(no, '女主角說不願意,求婚失敗'));

介紹 Async

使用 async function

mdn語法:

async function name([param[, param[, ...param]]]) {
   statements
}

呼叫 Async function,返回值會是 Promise物件

  • 當 return 是一個值 ex: Promise { 1 }

  • 當沒有 return 時 ex: Promise { undefined }

async function foo() {
    return 1;
}

console.log(foo()); //返回值是一個promise


注意 : Promise 物件可以使用 then methods

複習一下 : result 是 Promise 物件可以使用 then 在這之前會經由 reslove / reject 解析出值

function nini() {
    let result = new Promise(function (reslove, reject) {
        console.log('nini:你在哪裡');
        setTimeout(() => {
            reslove('渣男:我在家裡啊');
        }, 1000);
    });

    return result;
}
nini().then(function (x) {
    console.log(x);
});

那既然 Async function 回傳值是一個 Promise 物件,試試用 then methods

function nini() {
    let result = new Promise(function (resolve, reject) {
        reslove('nini:你在哪裡');
    });

    return result;
}
nini().then((x) => console.log(x));

async function kiki() {
    return 'kiki:在哪裡';
}

kiki().then((y) => console.log(y));

在這裡你會疑惑!明明我自己寫 async function kiki() 返回值是字串啊!!!

才不是返回什麼 promise 物件咧,因為他被偷偷處理了

原始

async function kiki() {
    return 'kiki:在哪裡';
}

處理時

function kiki() {
    return new Promise(function (resolve, reject) {
        resolve('kiki:在哪裡');
    });
}

kiki().then((y) => console.log(y));

但要注意不是相等只是等價喔~


介紹 await

async function 內可以使用 await,可以和 Promise 搭配一起使用

async function 內包含 await 表達式,此表達式可以0~多個

async function kiki() {
    let result = await new Promise(function (reslove, reject) {
        resolve('kiki:在哪裡');
    });
    console.log(result);//kiki:在哪裡
}

執行方式:遇到 await 會停下來等解析完畢會回傳給 await 再 return 出去賦值給 result ,

因此可以把非同步用的像是同步


在學 Promsie 時要做到 promise chain 會在 then() 內 return 另一個 function ,

如果忘記快來複習一下:渣男給不完的promise

但在 Async function 和 await 表達式可以更輕鬆做到

執行完第一句await再執行第二句 await,不是同步執行~

原本建置 promise chain 是一次建起,現在可以分段建構

若await和非new promise物件使用

會轉成 resolve Promise 傳給 await 回傳出去

async function woman() {
    const result = await 100000;
    console.log(result); // 100000
}

woman();

發生錯誤時

沒錯又要再複習一下 promise,因為金魚腦的我,必須一直複習才能加深印象。

當發生錯誤無法成功執行時會走到 promise 內的 reject function,

then 內的 reject function 會收到

但 async await 方式會使用try...catch 來捕捉錯誤

利用前天寫的 promise 來改寫試試

原始:

function woman() {
    let randomNumber = Math.random() * 3;
    let random = Math.floor(randomNumber);
    return new Promise(function (resolve, reject) {
        if (random === 1) {
            return resolve('嫁');
        } else {
            return reject('不嫁');
        }
    });
}
woman()
    .then((yes) => console.log(yes, '女主角說願意,求婚成功'))
    .catch((no) => console.log(no, '女主角說不願意,求婚失敗'));
    
async function woman() {
    let randomNumber = Math.random() * 3;
    let random = Math.floor(randomNumber);
    try {
        let result = await new Promise(function (resolve, reject) {
            if (random === 1) {
                resolve('嫁');
            } else {
                throw '不嫁';
            }
        });
        console.log(result, '女主角說願意,求婚成功');
    } catch (error) {
        console.log(error, '女主角說不願意,求婚失敗');
    }
}

woman();


今天的我又進化了一點

把 new Promise 拉到外面寫,wow

function marry() {
    return new Promise((resolve, reject) => {
        let randomNumber = Math.random() * 3;
        let random = Math.floor(randomNumber);
        if (random === 1) {
            resolve('嫁');
        } else {
            reject('不嫁');
        }
    });
}

async function woman() {
    try {
        let result = await marry();
        console.log(result, '女主角說願意,求婚成功');
    } catch (error) {
        console.log(error, '女主角說不願意,求婚失敗');
    }
}

又在練習另一種方式

利用 async會自動轉 promise 物件來和 await 運算子試試

async function marry() {
    let randomNumber = Math.random() * 3;
    let random = Math.floor(randomNumber);
    try {
        if (random === 1) {
            return '嫁';
        } else {
            throw new Error('不嫁');
        }
    } catch (error) {
        throw error;
    }
}
async function woman() {
    try {
        let result = await marry();
        console.log(result, '女主角說願意,求婚成功');
    } catch (error) {
        console.log(error, '女主角說不願意,求婚失敗');
    }
}

今日學習就到這了~真的很累

很推薦 JavaScript 概念三明治:基礎觀念、語法原理一次帶走寫的 async 跟 await 推推推

觀念簡單又清晰,解救了水深火熱的我,原本超級不懂一看就上手

寫完 Async 又再次順便複習 promise ,更加熟練也能理解

"可以更簡單的使用 Promise "的意思

當沒有 async 跟 await 時會要一直使用 then 去接值,接完值想要再執行

function 的話,會在then 內返回 function

但使用 async 跟 await 可以直接在 async function 內做好

就剩明天了~~~自我精神喊話加油!!

資料參考:
mdn
JavaScript概念三明治:基礎觀念、語法原理一次帶走!
0 陷阱!0 誤解!8 天重新認識 JavaScript!(iT邦幫忙鐵人賽系列書 - 02)


上一篇
初學者跪著學JavaScript Day28 : 學迭代,學習不等待
下一篇
初學者跪著學JavaScript Day30 : 初學者跪著學JavaScript 到微蹲了嗎
系列文
初學者跪著學JavaScript30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

1 則留言

0
Chiahsuan
iT邦新手 4 級 ‧ 2021-10-14 18:20:44

這張圖充滿希望~~~/images/emoticon/emoticon37.gif

wendy iT邦新手 2 級 ‧ 2021-10-14 19:17:32 檢舉

因為要完賽了又充滿希望/images/emoticon/emoticon02.gif

我要留言

立即登入留言